﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using C3.XNA;
using Microsoft.Xna.Framework;
using SomeGame.Actors.Components;
using SomeGame.Actors.Components.Health;
using SomeGame.Actors.Components.Mind;
using SomeGame.Actors.Components.State;
using SomeGame.Actors.Types;
using SomeGame.Tools;
using SomeGame.Zones;

namespace SomeGame {

    public static class PhysicsEngine {

        public static void Update(GameTime gameTime) {

            // Triggers executed by player collision.
            for (int i = 0; i < ZoneManager.CurrentZone.Triggers.Count; i++) {
                if (GameEngine.Player.Body.Bounds.Intersects(ZoneManager.CurrentZone.Triggers[i].Body.Bounds)) {
                    ZoneManager.CurrentZone.Triggers[i].Execute();
                    ZoneManager.CurrentZone.Triggers[i].Enabled = false;
                }
            }

            // ToggleSwitches executed by player collision.
            for (int i = 0; i < ZoneManager.CurrentZone.ToggleSwitches.Count; i++) {
                if (GameEngine.Player.Body.Bounds.Intersects(ZoneManager.CurrentZone.ToggleSwitches[i].Body.Bounds)) {
                    ZoneManager.CurrentZone.ToggleSwitches[i].Execute();
                    ZoneManager.CurrentZone.ToggleSwitches[i].IsBeingTouched = true;
                } else {
                    ZoneManager.CurrentZone.ToggleSwitches[i].IsBeingTouched = false;
                }
            }

			// Check if any Zombies have hit a Zone wall.
	        foreach (var zombie in ZoneManager.CurrentZone.PlayerLevelActors.Where(x => x is Zombie)) {
		        if (zombie.GetComponent<Body>().Bounds.Intersects(ZoneManager.CurrentZone.Bounds)) {
			        // TODO: Change direction.
		        }
	        }
        }

        // TODO: This is a mess.
	    public static void DoBulletCollision(Body playerBody, IList<Actor> targets) {
		    if (!targets.Any()) {
			    return;
		    }
            // Trim the targets down to only those in front of the player.
		    if (playerBody.FacingDirection == FacingDirection.Right) {
				targets = targets.Where(x => x.GetComponent<Body>().Bounds.Left >= playerBody.Bounds.Right).OrderBy(x => x.GetComponent<Body>().Position.X).ToList();
		    } else {
				targets = targets.Where(x => x.GetComponent<Body>().Bounds.Right <= playerBody.Bounds.Left).OrderByDescending(x => x.GetComponent<Body>().Position.X).ToList();
		    }
            // Check for empty list again after trimming on FacingDirection.
		    if (!targets.Any()) { 
			    return;
		    }
            // Shotgun fires 7 pellets.
            /*DebugHelper.ShotgunPellets.Clear();*/
	        for (int j = 0; j < 7; j++) {
	            Vector2[] bulletPath = GraphicsHelper.GetBulletPath(playerBody);
                /*DebugHelper.ShotgunPellets.Add(bulletPath);*/
	            for (int i = 0; i < targets.Count; i++) {
	                if (targets[i] is Zombie && 
                        (targets[i]).GetComponent<ZombieMind>().StateMachine.CurrentState != ZombieStateMachine.State.Dying &&
                        (targets[i]).GetComponent<ZombieMind>().StateMachine.CurrentState != ZombieStateMachine.State.Dead &&
                        (targets[i]).GetComponent<ZombieMind>().StateMachine.CurrentState != ZombieStateMachine.State.Gibbed &&
                        (targets[i]).GetComponent<ZombieMind>().StateMachine.CurrentState != ZombieStateMachine.State.Goo &&
                        GraphicsHelper.LineSegmentIntersectsRectangle(targets[i].GetComponent<Body>().Bounds, bulletPath[0], bulletPath[1])) {
	                    targets[i].GetComponent<ZombieHealth>().ReduceHealth(GameEngine.Random.Next(5, 16)); // Each pellet does 5-15 damage.
	                    break;
	                }
	            }
	        }
	    }

    }

}